package com.ruoyi.fun.service.impl;

import java.util.List;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.exception.ServiceException;

import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.fun.mapper.EcStockLogMapper;
import com.ruoyi.fun.domain.EcStockLog;
import com.ruoyi.fun.service.IEcStockLogService;
import com.ruoyi.fun.service.IEcProductSkuService;
import com.ruoyi.fun.service.IEcStockService;
import com.ruoyi.fun.domain.EcProductSku;

/**
 * 库存记录Service业务层处理
 * 
 * @author ruoyi
 * @date 2025-08-06
 */
@Service
public class EcStockLogServiceImpl implements IEcStockLogService 
{
    @Autowired
    private EcStockLogMapper ecStockLogMapper;
    
    @Autowired
    private IEcProductSkuService ecProductSkuService;
    
    @Autowired
    private IEcStockService ecStockService;

    /**
     * 查询库存记录
     * 
     * @param logId 库存记录主键
     * @return 库存记录
     */
    @Override
    public EcStockLog selectEcStockLogByLogId(Long logId)
    {
        return ecStockLogMapper.selectEcStockLogByLogId(logId);
    }

    /**
     * 查询库存记录列表
     * 
     * @param ecStockLog 库存记录
     * @return 库存记录
     */
    @Override
    public List<EcStockLog> selectEcStockLogList(EcStockLog ecStockLog)
    {
        return ecStockLogMapper.selectEcStockLogList(ecStockLog);
    }

    /**
     * 新增库存记录
     * 
     * @param ecStockLog 库存记录
     * @return 结果
     */
    @Override
    public int insertEcStockLog(EcStockLog ecStockLog)
    {
        ecStockLog.setCreateTime(DateUtils.getNowDate());
        Long orgId = ecStockLog.getOrgId();
        if (orgId == null) {
            orgId = SecurityUtils.getDeptId();
            ecStockLog.setOrgId(orgId);
        }
        
        // 如果有SKU ID，同步更新SKU库存
        if (ecStockLog.getSkuId() != null && ecStockLog.getOperationQuantity() != null && ecStockLog.getOperationType() != null) {
            try {
                // 获取当前库存
                Long currentStock = ecStockService.getCurrentStock(ecStockLog.getSkuId());
                ecStockLog.setBeforeStock(currentStock);
                
                // 根据操作类型计算库存变化量
                Long operationQuantity = ecStockLog.getOperationQuantity();
                Long stockIncrement = 0L;
                Long afterStock = currentStock;
                
                if ("1".equals(ecStockLog.getOperationType())) {
                    // 1 = 入库：操作数量为正数时增加库存，负数时减少库存
                    afterStock = currentStock + operationQuantity;
                    stockIncrement = operationQuantity;
                } else if ("2".equals(ecStockLog.getOperationType())) {
                    // 2 = 出库：操作数量为正数时减少库存，负数时增加库存
                    afterStock = currentStock - operationQuantity;
                    stockIncrement = -operationQuantity;
                } else if ("3".equals(ecStockLog.getOperationType())) {
                    // 3 = 调整：直接设置为目标库存数量
                    afterStock = operationQuantity;
                    stockIncrement = operationQuantity - currentStock;
                }
                
                // 确保库存数量不小于0
                if (afterStock < 0) {
                    afterStock = 0L;
                    // 重新计算库存变化量
                    stockIncrement = afterStock - currentStock;
                }
                
                ecStockLog.setAfterStock(afterStock);
                
                // 同步更新SKU库存
                ecProductSkuService.updateSkuStock(ecStockLog.getSkuId(), stockIncrement, orgId);
                
            } catch (Exception e) {
                System.out.println("新增库存记录时同步更新SKU库存失败: " + e.getMessage());
                // 不抛出异常，允许库存记录正常插入
            }
        }
        
        return ecStockLogMapper.insertEcStockLog(ecStockLog);
    }

    /**
     * 修改库存记录
     * 
     * @param ecStockLog 库存记录
     * @return 结果
     */
    @Override
    public int updateEcStockLog(EcStockLog ecStockLog)
    {
        return ecStockLogMapper.updateEcStockLog(ecStockLog);
    }

    /**
     * 批量删除库存记录
     * 
     * @param logIds 需要删除的库存记录主键
     * @return 结果
     */
    @Override
    public int deleteEcStockLogByLogIds(Long[] logIds)
    {
        Long orgId = SecurityUtils.getDeptId();
        return ecStockLogMapper.deleteEcStockLogByLogIds(logIds, orgId);
    }

    /**
     * 删除库存记录信息
     * 
     * @param logId 库存记录主键
     * @return 结果
     */
    @Override
    public int deleteEcStockLogByLogId(Long logId)
    {
        Long orgId = SecurityUtils.getDeptId();
        return ecStockLogMapper.deleteEcStockLogByLogId(logId, orgId);
    }

    /**
     * 根据logId和组织ID查询StockLog
     * 
     * @param logId StockLog主键
     * @param orgId 组织ID
     * @return StockLog
     */
    @Override
    public EcStockLog selectEcStockLogByLogIdAndOrgId(Long logId, Long orgId)
    {
        return ecStockLogMapper.selectEcStockLogByLogIdAndOrgId(logId, orgId);
    }

    /**
     * 根据组织ID查询StockLog列表
     * 
     * @param ecstocklog StockLog
     * @param orgId 组织ID
     * @return StockLog集合
     */
    @Override
    public List<EcStockLog> selectEcStockLogListByOrgId(EcStockLog ecstocklog, Long orgId)
    {
        return ecStockLogMapper.selectEcStockLogListByOrgId(ecstocklog, orgId);
    }

    /**
     * 导入库存记录数据
     * 
     * @param logList 库存记录数据列表
     * @param updateSupport 是否更新支持，如果已存在，则进行更新数据
     * @param operName 操作用户
     * @param orgId 组织ID
     * @return 结果
     */
    @Override
    public String importStockLog(List<EcStockLog> logList, Boolean updateSupport, String operName, Long orgId)
    {
        if (ObjectUtils.isEmpty(orgId) || logList.isEmpty())
        {
            throw new ServiceException("导入库存记录数据不能为空！");
        }
        int successNum = 0;
        int failureNum = 0;
        StringBuilder successMsg = new StringBuilder();
        StringBuilder failureMsg = new StringBuilder();
        
        for (int i = 0; i < logList.size(); i++)
        {
            EcStockLog log = logList.get(i);
            int rowNum = i + 2; // Excel行号从2开始（第1行是标题）
            
            try
            {
                // 设置组织ID和操作人
                log.setOrgId(orgId);
                log.setCreateBy(operName);
                log.setCreateTime(DateUtils.getNowDate());
                
                // 验证必填字段
                if (StringUtils.isEmpty(log.getSkuId()+"") || StringUtils.isEmpty(log.getOperationType()))
                {
                    failureNum++;
                    String errorDetail = "";
                    if (StringUtils.isEmpty(log.getSkuId()+"")) {
                        errorDetail += "SKU ID不能为空";
                    }
                    if (StringUtils.isEmpty(log.getOperationType())) {
                        if (!errorDetail.isEmpty()) errorDetail += "，";
                        errorDetail += "操作类型不能为空（请填写：入库、出库或调整）";
                    }
                    failureMsg.append("<br/>第").append(rowNum).append("行：").append(errorDetail);
                    continue;
                }
                
                // 验证操作数量
                if (log.getOperationQuantity() == null) {
                    failureNum++;
                    failureMsg.append("<br/>第").append(rowNum).append("行：操作数量不能为空");
                    continue;
                }
                
                // 验证操作类型格式
                if (!"1".equals(log.getOperationType()) && !"2".equals(log.getOperationType()) && !"3".equals(log.getOperationType())) {
                    failureNum++;
                    failureMsg.append("<br/>第").append(rowNum).append("行：操作类型 '").append(log.getOperationType()).append("' 无效，请填写：入库、出库或调整");
                    continue;
                }
                
                // 根据SKU ID获取商品ID
                if (log.getSkuId() != null && log.getProductId() == null)
                {
                    EcProductSku sku = ecProductSkuService.selectEcProductSkuBySkuIdAndOrgId(log.getSkuId(), orgId);
                    if (sku != null)
                    {
                        log.setProductId(sku.getProductId());
                    }
                    else
                    {
                        failureNum++;
                        failureMsg.append("<br/>第").append(rowNum).append("行：SKU ID ").append(log.getSkuId()).append(" 在系统中不存在或不属于当前组织，请检查SKU ID是否正确");
                        continue;
                    }
                }
                
                // 计算before_stock和after_stock
                if (log.getSkuId() != null)
                {
                    // 获取当前库存作为操作前库存
                    Long currentStock = ecStockService.getCurrentStock(log.getSkuId());
                    log.setBeforeStock(currentStock);
                    
                    // 根据操作类型计算操作后库存和实际库存变化量
                    Long operationQuantity = log.getOperationQuantity() != null ? log.getOperationQuantity() : 0L;
                    Long afterStock = currentStock;
                    Long stockIncrement = 0L; // 实际库存变化量
                    
                    if ("1".equals(log.getOperationType())) {
                        // 1 = 入库：操作数量为正数时增加库存，负数时减少库存
                        afterStock = currentStock + operationQuantity;
                        stockIncrement = operationQuantity;
                    } else if ("2".equals(log.getOperationType())) {
                        // 2 = 出库：操作数量为正数时减少库存，负数时增加库存
                        afterStock = currentStock - operationQuantity;
                        stockIncrement = -operationQuantity;
                    } else if ("3".equals(log.getOperationType())) {
                        // 3 = 调整：直接设置为目标库存数量
                        if (operationQuantity < 0) {
                            failureNum++;
                            failureMsg.append("<br/>第").append(rowNum).append("行：调整操作的目标库存数量不能为负数，当前值：").append(operationQuantity);
                            continue;
                        }
                        afterStock = operationQuantity;
                        stockIncrement = operationQuantity - currentStock;
                    } else {
                        failureNum++;
                        failureMsg.append("<br/>第").append(rowNum).append("行：操作类型 ").append(log.getOperationType()).append(" 无效，只支持：1=入库，2=出库，3=调整");
                        continue;
                    }
                    
                    // 确保库存数量不小于0
                    if (afterStock < 0) {
                        afterStock = 0L;
                        // 重新计算库存变化量
                        stockIncrement = afterStock - currentStock;
                    }
                    
                    log.setAfterStock(afterStock);
                    
                    // 同步更新SKU库存
                    try {
                        int updateResult = ecProductSkuService.updateSkuStock(log.getSkuId(), stockIncrement, orgId);
                        if (updateResult <= 0) {
                            failureNum++;
                            failureMsg.append("<br/>第").append(rowNum).append("行：SKU ID ").append(log.getSkuId()).append(" 库存更新失败，可能是数据库操作异常");
                            continue;
                        }
                    } catch (Exception e) {
                        failureNum++;
                        failureMsg.append("<br/>第").append(rowNum).append("行：SKU ID ").append(log.getSkuId()).append(" 库存更新异常：").append(e.getMessage());
                        continue;
                    }
                }
                
                // 插入库存记录
                try {
                    this.insertEcStockLog(log);
                    successNum++;
                    successMsg.append("<br/>").append(successNum).append("、第").append(rowNum).append("行库存记录 SKU ID ").append(log.getSkuId()).append(" 导入成功");
                } catch (Exception e) {
                    failureNum++;
                    failureMsg.append("<br/>第").append(rowNum).append("行：库存记录插入失败：").append(e.getMessage());
                    continue;
                }
            }
            catch (Exception e)
            {
                failureNum++;
                String msg = "<br/>第" + rowNum + "行：库存记录处理失败：";
                failureMsg.append(msg).append(e.getMessage());
            }
        }
        
        if (failureNum > 0)
        {
            failureMsg.insert(0, "很抱歉，导入失败！共 " + failureNum + " 条数据存在问题，错误详情如下：");
            throw new ServiceException(failureMsg.toString());
        }
        else
        {
            successMsg.insert(0, "恭喜您，数据已全部导入成功！共 " + successNum + " 条，详情如下：");
        }
        return successMsg.toString();
    }
}